﻿using JTG.ServiceInterface.Factory;
using JTG.ServiceInterface.InterfaceService;
using JTG.ServiceInterface.Model;
using Newtonsoft.Json;
using Spire.Pdf;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Drawing;
using System.Drawing.Printing;
using System.Linq;
using System.Threading;
using Tzw.Common;
using Tzw.Common.Model;

namespace JTG.CheckInMachine.Zzzyy
{
    public partial class ReadCard : BaseForm
    {
        private IPrinterService _printerService;
        private List<PrinterInfo> _printerInfos;
        private PrinterHelper _printer = new PrinterHelper();
        private static string _funcName = ConfigurationManager.AppSettings["ConfigReflectionFunc"];
        private string _isTest = ConfigurationManager.AppSettings["IsTest"];
        private ZzzyyService _zzzyyService;
        private FtpHelper _ftpHelper;

        private int _timeOutClose = App.GlobSettings.OperateShowTimes;
        private int _w;
        private int _h;

        List<ZzzyyReportInfo> _reportInfos;
        private bool _isShowDialog;

        public ReadCard(int w, int h) : base(w, h)
        {
            _w = w;
            _h = h;
            InitializeComponent();
            _zzzyyService = new ZzzyyService();
        }

        private void Main_Load(object sender, System.EventArgs e)
        {
            //关闭按钮事件
            CloseEvent += (s, e1) =>
            {
                pwdKeyboard1.CloseTimeReset();
                pwdKeyboard1.Visible = true;
            };

            pwdKeyboard1.CloseEvent += (o, args) => { Close(); };

            textBox1.GotFocus += TextBox1_GotFocus;
            keyboard.NumberEvent += NumberEvent;
            keyboard.OkEvent += OkEvent;
            keyboard.CleanEvent += CleanEvent;
            keyboard.DeleteEvent += DeleteEvent;

            base_lab_time.Visible = false; //隐藏时间lab

            this.BackgroundImage = Image.FromFile("Imgs\\zzzyy\\资中县中医医院-电子健康卡.jpg");

            //文本输入框
            textBox1.Left = 424;
            textBox1.Top = 157;

            //键盘
            keyboard.Width = 408;
            keyboard.Height = 368;
            keyboard.Left = 276;
            keyboard.Top = 232;

            //扫条码gif动画
            lab_sacnqrcode.Width = 419;
            lab_sacnqrcode.Height = 425;
            lab_sacnqrcode.Left = 272;
            lab_sacnqrcode.Top = 198;

            //等待动画
            lab_loading.Left = 480;
            lab_loading.Top = 330;

            //加载打印机检查服务
            _printerService = new PrintServiceFactory().CreatePrintService();

            _ftpHelper = new FtpHelper(ConfigurationManager.AppSettings["FtpIp"], ConfigurationManager.AppSettings["FtpPath"],
                ConfigurationManager.AppSettings["FtpUser"], ConfigurationManager.AppSettings["FtpPwd"]);
        }

#region 键盘事件

        private void NumberEvent(object sender, EventArgs e)
        {
            textBox1.Text += sender.ToString();
            _timeOutClose = App.GlobSettings.OperateShowTimes;
        }

        private void OkEvent(object sender, EventArgs e)
        {
            btn_ok_Click(sender, e);
            _timeOutClose = App.GlobSettings.OperateShowTimes;
        }

        private void DeleteEvent(object sender, EventArgs e)
        {
            if (textBox1.Text.Length > 0)
                textBox1.Text = textBox1.Text.Substring(0, textBox1.Text.Length - 1);
            _timeOutClose = App.GlobSettings.OperateShowTimes;
        }

        private void CleanEvent(object sender, EventArgs e)
        {
            textBox1.Text = "";
            _timeOutClose = App.GlobSettings.OperateShowTimes;
        }

#endregion

        private void btn_KeyBoard_Click(object sender, System.EventArgs e)
        {
            keyboard.Visible = !keyboard.Visible;
            lab_sacnqrcode.Visible = !keyboard.Visible;
            textBox1.Focus();
        }


        private void btn_ok_Click(object sender, System.EventArgs e)
        {
            //数据交互，界面等待中
            DataTrans(true);
            
            //异步对接lis
            var t = new Thread(() =>
            {
                try
                {
                    //加载打印机信息
                    _printerInfos = _printerService.GetList();

                    Enums.ReportStatus printStatus;
                    var printName = "";

                    //打印机错误
                    if (_printerInfos == null || !_printerInfos.Any() || _printerInfos.Any(x => x.Status != 1))
                    {
                        Logger.Default.Debug($"打印机信息:{JsonConvert.SerializeObject(_printerInfos)}");
                        printStatus = Enums.ReportStatus.Error;
                    }
                    else
                    {
                        //1查询病人信息 测试ID：F15D6F66F868650A0A891EDC64FEE7C867CD28CA17289EF7EC0DCD564C08E231
                        var brid = _zzzyyService.GetPatientIdByCardId(textBox1.Text.Split(':')[0]);

                        printStatus = Enums.ReportStatus.NoReport;

                        //病人id不存在
                        if (string.IsNullOrEmpty(brid))
                        {
                            Logger.Default.Debug("病人id不存在");
                            ShowResult(printStatus, printName);
                            return;
                        }

                        //2查询已缴费的报告
                        _reportInfos = _zzzyyService.LisReportQuery(brid);

                        //没有可打印的报告
                        if (!_reportInfos.Any())
                        {
                            Logger.Default.Debug("该病人无报告");
                            ShowResult(printStatus, printName);
                            return;
                        }

                        if (_isTest.Equals("true"))
                        {
                            _reportInfos.ForEach(x => { x.ZT = x.ZT == "已打印" ? "可打印" : x.ZT; });
                        }

                        //是否存在待检验报告
                        if (_reportInfos.Any(x => x.ZT.Equals("检验中")))
                        {
                            printStatus = Enums.ReportStatus.NoResult;
                            Logger.Default.Debug("有检验中的报告");
                        }

                        //获取可以打印的报告
                        var lisReportQuery = _reportInfos.Where(x => x.ZT.Equals("可打印")).ToList();
                        if (!lisReportQuery.Any())
                        {
                            Logger.Default.Debug("该病人无可打印报告");
                            ShowResult(printStatus, printName);
                            return;
                        }

                        if (lisReportQuery.Any() && printStatus == Enums.ReportStatus.NoResult)
                        {
                            Logger.Default.Debug("有打印报告同时还有检验未出报告");
                            printStatus = Enums.ReportStatus.PrintingAndHasReport;
                        }
                        else
                        {
                            Logger.Default.Debug("有可打印报告");
                            printStatus = Enums.ReportStatus.Printing;
                        }

                        //打印前切换打印机
                        if (Enums.ReportStatus.Printing == printStatus || Enums.ReportStatus.PrintingAndHasReport == printStatus)
                        {
                            printName = _printer.ChangePrinter(_printerInfos); //设置默认打印机

                            //设置灯光 TODO
                        }

                        //查询病人报告，并打印
                        foreach (var lisInfo in lisReportQuery)
                        {
                            new Thread(obj =>
                            {
                                var info = (ZzzyyReportInfo)obj;
                                try
                                {
                                    //3查询需要打印的报告url
                                    var urls = _zzzyyService.GetReportUrl(info.YZID, info.BRID);

                                    if (!urls.Any())
                                    {
                                        info.ExtPrintStatus = 2;

                                        ShowResult(Enums.ReportStatus.NoReport, printName);

                                        return;
                                    }

                                    foreach (var url in urls)
                                    {
                                        Logger.Default.Debug($"{info.YZID},{info.BRID}，文档地址：{url}");

                                        var pdfStream = _ftpHelper.GetFileStream($"{url.Split('/').Last()}.pdf");

                                        //加载PDF文档
                                        var doc = new PdfDocument();
                                        doc.LoadFromStream(pdfStream);

                                        //静默打印PDF文档
                                        doc.PrintSettings.PrintController = new StandardPrintController();
                                        doc.Print();

                                        info.ExtPrintStatus = 1;

                                        ShowResult(printStatus, printName);

                                        doc.Dispose();
                                        pdfStream.Close();
                                    }

                                    //4回写打印状态
                                    _zzzyyService.LitPrintCallBack(info.BRID, info.YBTM);
                                }
                                catch (Exception exception)
                                {
                                    Logger.Default.Error(
                                        $"打印报告异常：{exception.Message},{exception.StackTrace},\r\n打印数据：{JsonConvert.SerializeObject(_reportInfos)}");

                                    info.ExtPrintStatus = 2;

                                    ShowResult(Enums.ReportStatus.NoReport, printName);
                                }

                            }).Start(lisInfo);
                        }
                    }

                }
                catch (Exception ex)
                {
                    Logger.Default.Error($"lis对接异常，异常信息：{ex.Message},{ex.StackTrace}", ex);

                    ShowResult(Enums.ReportStatus.NoReport, "");

                    Invoke(new Action(() =>
                    {
                        textBox1.Text = "";
                        DataTrans(false);
                        textBox1.Focus();
                    }));
                }

            });
            t.IsBackground = true;
            t.Start();

        }

        /// <summary>
        /// 显示界面(处理多线程问题，只要有一个可以打印就展示打印界面，所有报告未获取到打印信息则显示无可用打印信息)
        /// </summary>
        /// <param name="printStatus"></param>
        /// <param name="printName"></param>
        /// <param name="status"></param>
        private void ShowResult(Enums.ReportStatus printStatus, string printName)
        {
            try
            {
                Logger.Default.Debug($"显示状态{_isShowDialog}，打印数据：{JsonConvert.SerializeObject(_reportInfos)}");

                if (_isShowDialog) return;

                //在多线程的情况下，可能有的线程为获得pdf，则坚持是否存已读取完pdf，如果所有pdf都未读取到则显示没有可以打印报告
                if (_reportInfos != null && printStatus != Enums.ReportStatus.PrintingAndHasReport && printStatus != Enums.ReportStatus.Printing)
                {
                    //有可打印的报告
                    var canPrints = _reportInfos.Where(x => x.ZT.Equals("可打印")).ToList();
                    if (canPrints.Any(x => x.ExtPrintStatus != 1))
                    {
                        Logger.Default.Debug($"有可以打印报告数量{canPrints.Count()}");
                        //还没完全读出pdf内容
                        if (canPrints.Count(x => x.ExtPrintStatus != 0) != canPrints.Count())
                        {
                            Logger.Default.Debug($"报告未查询完");
                            return;
                        }

                        Logger.Default.Debug($"未获取到报告");
                        //无可用打印报告
                        printStatus = Enums.ReportStatus.NoReport;
                    }
                }

                _isShowDialog = true;

                //展示窗口
                new ShowInfo(printStatus, _w, _h, _printerService, printName).ShowDialog();

                _isShowDialog = false;

                Invoke(new Action(() =>
                {
                    textBox1.Text = "";
                    DataTrans(false);
                    textBox1.Focus();
                }));
            }
            catch (Exception ex)
            {
                Logger.Default.Error($"ShowResult异常：{ex.Message},{ex.StackTrace}");
            }
        }

        private void TextBox1_GotFocus(object sender, EventArgs e)
        {
            textBox1.Select(0, textBox1.Text.Length);
        }

        /// <summary>
        /// 窗口激活，输入框获得焦点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Main_Activated(object sender, EventArgs e)
        {
            textBox1.Focus();
        }

        /// <summary>
        /// 隐藏键盘，动画；显示等待；输入框不可用，按钮不可用
        /// </summary>
        /// <param name="hide"></param>
        public void DataTrans(bool hide)
        {
            if (hide)
            {
                lab_sacnqrcode.Visible = false;
                keyboard.Visible = false;
                textBox1.Enabled = false;

                lab_loading.Visible = true;
            }
            else
            {
                lab_sacnqrcode.Visible = true;
                keyboard.Visible = false;
                textBox1.Enabled = true;

                lab_loading.Visible = false;
            }
        }

    }
}